package com.supreme.threadserver.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.supreme.commonboot.utils.AjaxResp;
import com.supreme.commonentity.mysql.primary.BatchBase;
import com.supreme.commonentity.mysql.primary.BizUser;
import com.supreme.commonmybatis.mapper.BizUserMapper;
import com.supreme.threadserver.entity.reqdata.CreateOrderProcessBody;
import com.supreme.threadserver.service.AsyncThreadService;
import com.supreme.threadserver.service.JucTransactionService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
@RequestMapping(value = "transaction")
public class TransactionController {

    @Resource
    private BizUserMapper bizUserMapper;

    @Resource
    private JucTransactionService jucTransactionService;

    @Resource
    private AsyncThreadService asyncThreadService;

    @PostMapping(value = "insertBizUserList")
    public AjaxResp insertBizUserList(@RequestBody List<BizUser> users) {
        Future<Boolean> booleanFuture = jucTransactionService.insertBizUserList(users);
        Boolean result;
        try {
            result = booleanFuture.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
        return AjaxResp.instance(result);
    }

    @GetMapping(value = "selectBizUserList")
    public AjaxResp selectBizUserList() {
        List<BizUser> bizUserList = bizUserMapper.selectList(Wrappers.lambdaQuery(BizUser.class));
        return AjaxResp.instance(bizUserList);
    }

    @PostMapping(value = "createOrderProcess")
    public AjaxResp createOrderProcess(@RequestBody CreateOrderProcessBody createOrderProcessBody) {
        String userCode = createOrderProcessBody.getUserCode();
        String goodsCode = createOrderProcessBody.getGoodsCode();
        Integer stockNum = createOrderProcessBody.getStockNum();
        jucTransactionService.createOrderProcess(userCode, goodsCode, stockNum);
        return AjaxResp.instance();
    }

    @GetMapping(value = "createAllRandomBatchList")
    public AjaxResp createAllRandomBatchList(@RequestParam(value = "batchCode") String batchCode,
                                             @RequestParam(value = "expValue", defaultValue = "0", required = false) Integer expValue,
                                             @RequestParam(value = "async", defaultValue = "false") Boolean async) {
        List<BatchBase> batchBaseList;

        if (async) {
            CompletableFuture<List<BatchBase>> completableFuture = CompletableFuture.supplyAsync(() -> {
                jucTransactionService.createAllRandomBatchList(batchCode, expValue);
                List<BatchBase> baseBatchList = jucTransactionService.getBaseBatchList(batchCode);
                return baseBatchList;
            });

            try {
                batchBaseList = completableFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        } else {
            jucTransactionService.createAllRandomBatchList(batchCode, expValue);
            batchBaseList = jucTransactionService.getBaseBatchList(batchCode);
        }

        return AjaxResp.instance(batchBaseList);
    }

    @GetMapping(value = "createRandomBatchListSync")
    public AjaxResp createRandomBatchListSync(@RequestParam(value = "batchCode") String batchCode,
                                              @RequestParam(value = "expValue", defaultValue = "0", required = false) Integer expValue,
                                              @RequestParam(value = "async", defaultValue = "false") Boolean async) {
        List<BatchBase> batchBaseList;
        if (async) {
            Future<List<BatchBase>> listFuture = asyncThreadService.asyncCreateRandomBatchList(batchCode, expValue);
            try {
                batchBaseList = listFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        } else {
            jucTransactionService.createRandomBatchListSync(batchCode, expValue);
            batchBaseList = jucTransactionService.getBaseBatchList(batchCode);
        }

        return AjaxResp.instance(batchBaseList);
    }

    @GetMapping(value = "createRandomBatchListAsync1")
    public AjaxResp createRandomBatchListAsync1(@RequestParam(value = "batchCode") String batchCode,
                                             @RequestParam(value = "expValue", defaultValue = "0", required = false) Integer expValue) {
        jucTransactionService.createRandomBatchListAsync1(batchCode, expValue);
        List<BatchBase> baseBatchList = jucTransactionService.getBaseBatchList(batchCode);
        return AjaxResp.instance(baseBatchList);
    }

    @GetMapping(value = "createRandomBatchListAsync2")
    public AjaxResp createRandomBatchListAsync2(@RequestParam(value = "batchCode") String batchCode,
                                             @RequestParam(value = "expValue", defaultValue = "0", required = false) Integer expValue) {
        jucTransactionService.createRandomBatchListAsync2(batchCode, expValue);
        List<BatchBase> baseBatchList = jucTransactionService.getBaseBatchList(batchCode);
        return AjaxResp.instance(baseBatchList);
    }

    @GetMapping(value = "createRandomBatchListComplete1")
    public AjaxResp createRandomBatchListComplete1(@RequestParam(value = "batchCode") String batchCode,
                                             @RequestParam(value = "expValue", defaultValue = "0", required = false) Integer expValue) {
        jucTransactionService.createRandomBatchListComplete1(batchCode, expValue);
        List<BatchBase> baseBatchList = jucTransactionService.getBaseBatchList(batchCode);
        return AjaxResp.instance(baseBatchList);
    }

    @GetMapping(value = "createRandomBatchListComplete2")
    public AjaxResp createRandomBatchListComplete2(@RequestParam(value = "batchCode") String batchCode,
                                             @RequestParam(value = "expValue", defaultValue = "0", required = false) Integer expValue) {
        jucTransactionService.createRandomBatchListComplete2(batchCode, expValue);
        List<BatchBase> baseBatchList = jucTransactionService.getBaseBatchList(batchCode);
        return AjaxResp.instance(baseBatchList);
    }

    @GetMapping(value = "createRandomBatchListComplete3")
    public AjaxResp createRandomBatchListComplete3(@RequestParam(value = "batchCode") String batchCode,
                                             @RequestParam(value = "expValue", defaultValue = "0", required = false) Integer expValue) {
        int syncVersion = jucTransactionService.createRandomBatchListComplete3(batchCode, expValue);
        List<BatchBase> baseBatchList = jucTransactionService.getBaseBatchList(batchCode);
        return AjaxResp.instance(baseBatchList).append("syncVersion", syncVersion);
    }
}
